package com.shop.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shop.feign.CartFeginService;
import com.shop.feign.MemberFeignService;
import com.shop.interceptor.LoginInterceptor;
import com.shop.mapper.Oms_Order_Mapper;
import com.shop.pojo.oms.Oms_Order;
import com.shop.pojo.ums.Ums_Member;
import com.shop.pojo.ums.Ums_Member_Receive_Address;
import com.shop.service.Oms_Order_Service;

import com.shop.vo.OrderConfirmVo;
import com.shop.vo.OrderItemVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import com.shop.utils.LayuiUtils;
import com.shop.utils.R;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 订单-后台
 */
@Service
public class Oms_Order_ServiceImpl extends ServiceImpl<Oms_Order_Mapper, Oms_Order> implements Oms_Order_Service {


    @Autowired
    private Oms_Order_Mapper oms_order_mapper;

    @Autowired
    MemberFeignService memberFeignService;

    @Autowired
    CartFeginService cartFeginService;

    //线程池
    @Autowired
    ThreadPoolExecutor executor;



    @Override
    public LayuiUtils<Oms_Order> find_oms_order(Page<Oms_Order> pages, Oms_Order oms_order) {
        LayuiUtils<Oms_Order> layuiUtils = new LayuiUtils<>();
        QueryWrapper<Oms_Order> queryWrapper = new QueryWrapper<>();
        if (oms_order.getOrder_sn() != null){
            queryWrapper.eq("order_sn",oms_order.getOrder_sn());
        }
        Page<Oms_Order> oms_orderPage = oms_order_mapper.selectPage(pages,queryWrapper);
        layuiUtils.setCount(oms_orderPage.getTotal());
        layuiUtils.setData(oms_orderPage.getRecords());
        return layuiUtils;
    }

    /**
     * 订单确认页面返回需要用到的数据
     * @return
     */
    @Override
    public R confirmOrder() throws ExecutionException, InterruptedException {
        OrderConfirmVo orderConfirmVo = new OrderConfirmVo();
        //获取当前登录的用户
        Ums_Member ums_member = LoginInterceptor.loginUser.get();
        //开启异步执行 feign的远程调用线路不一样所有请求头还是会再次的丢失 为了解决该问题
        //获取之前的原请求  在执行之前先放入数据  从主线程拿到原来的数据 在父线程里面共享数据 共享后拦截器可以获取到数据
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();

        //异步方式运行 远程查询
        CompletableFuture<Void> getAddress = CompletableFuture.runAsync(() -> {
            //Thread在自己的线程里在共享一下之前请求的数据数据
            RequestContextHolder.setRequestAttributes(requestAttributes);
            //1、远程查询所有订单的地址列表
            List<Ums_Member_Receive_Address> memberIdAddress = memberFeignService.getMemberIdAddress(ums_member.getId());
            orderConfirmVo.setAddress(memberIdAddress);
        }, executor);

        CompletableFuture<Void> getItems = CompletableFuture.runAsync(() -> {
            //Thread在自己的线程里在共享一下之前请求的数据数据
            RequestContextHolder.setRequestAttributes(requestAttributes);
            //2、远程查询购物项所选择的数据进行显示
            List<OrderItemVo> userByIdCartItems = cartFeginService.getUserByIdCartItems();
            orderConfirmVo.setItems(userByIdCartItems);
        }, executor);

        //feign在远程调用之前会构造请求   调用很多的拦截器  里面没有请求头 所以获取不到页面携带的cookie信息
        //3、查询用户的积分信息
        int integration = ums_member.getIntegration();
        orderConfirmVo.setIntegration(integration);
        //其他价格自动计算


        //等待所有的任务完成做一个完整的返回
        CompletableFuture.allOf(getAddress,getItems).get();

        //防止表单重复提交订单造成多余 防重复令牌

        //返回给页面信息数据
        if(orderConfirmVo.getItems() != null && orderConfirmVo.getItems().size() > 0){
            return R.success().data(orderConfirmVo);
        }
        return R.error(500,"请选择购买商品");
    }


}
